/**
 * 计算实体是否在圆上
 * @param a 圆的中心点坐标
 * @param r 圆的半径
 * @param q 圆的方向（四元数）
 * @param b 实体的坐标
 * @param tolerance 容差值，用于判断点是否在圆上的误差范围
 * @returns 如果实体在圆上返回true，否则返回false
 */
export function isEntityOnCircle(
    a: GameVector3,
    r: number,
    q: GameQuaternion,
    b: GameVector3,
    tolerance: number = 0.001
): boolean {
    // 1. 计算实体到圆心的向量
    const vectorFromCenter = b.clone().sub(a);

    // 2. 获取圆的法向量（四元数旋转后的x轴方向，符合垂直平面基准）
    // 注：单位四元数(0,0,0,1)时，法向量为(1,0,0)，圆平面垂直于水平面
    const circleNormal = new GameVector3(1, 0, 0); // 基准法向量改为x轴
    // eslint-disable-next-line no-use-before-define
    const rotatedNormal = applyQuaternionRotation(circleNormal, q);

    // 3. 计算实体到圆平面的距离（垂直距离）
    const distanceToPlane = Math.abs(vectorFromCenter.dot(rotatedNormal));

    // 4. 如果距离平面太远，直接返回false
    if (distanceToPlane > tolerance) {
        return false;
    }

    // 5. 计算实体在圆平面上的投影点
    const projection = vectorFromCenter
        .clone()
        .sub(rotatedNormal.clone().scale(distanceToPlane));

    // 6. 计算投影点到圆心的距离
    const distanceToCenter = projection.mag();

    // 7. 判断距离是否在圆的半径范围内（考虑容差）
    return Math.abs(distanceToCenter - r) <= tolerance;
}

/**
 * 应用四元数旋转到向量上
 * @param vector 要旋转的向量
 * @param quaternion 旋转四元数
 * @returns 旋转后的向量
 */
function applyQuaternionRotation(
    vector: GameVector3,
    quaternion: GameQuaternion
): GameVector3 {
    // 四元数旋转向量标准算法：v' = q * v * q^(-1)
    const vectorQuat = new GameQuaternion(0, vector.x, vector.y, vector.z);
    const inverseQuat = quaternion.clone().inv().normalize();
    const qv = quaternion.clone().mul(vectorQuat);
    const qvqInv = qv.mul(inverseQuat);
    return new GameVector3(qvqInv.x, qvqInv.y, qvqInv.z);
}
